/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import java.io.IOException;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.LayerManager;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;

/**
 *
 * @author Monster
 */
public class MH_Play extends GameCanvas implements Runnable {

    private Game app;
    private MH_Play mH_Play;
    private GameDesign design;
    private GameDesign_1 design1;
    private LayerManager layerManager;
    private long delay;
    private int status;
    private int EnemyStatus;
    private int iX, iY;
    private int KidDirection;
    private int KidState;
    private final int charWalk = 1;
    private final int charStop = 2;
    private int speed = 6;
    private Sprite BoomMan;
    private TiledLayer Base;
    private TiledLayer ChuongNgai;
    private TiledLayer Ground;
    private int DoLeft, DoRight, DoUp, DoDown;
    private int scnX = 0; //toa do goc trai khung nhin
    private int scnY = 0;
    private final int MIN_BUFFER = 50;
    public Timer time;
    //
    private Timer timer = null;
    private DieAnimation dieAnimation = null; //Xu ly khi chet
    private int isDatBom = 0; //kiem tra bom dat het so luong chua
    private int x;
    private int y;
    private NamDoc namDoc;
    private Sprite[] Gach;
    private int nGach = 23;
    private Sprite[] Monster;
    private NamDoc[] Monster_Animated;
    private int nMonster = 10;
    private int nAnemies = 10; // đếm số quái vật, khi tiêu diệt hết sẽ xuất hiện tướng.
    private Sprite Boss;
    private Boss Boss_Animated;
    private Sprite VatPham_BanhXe;
    private Sprite VatPham_Lua;
    private Sprite VatPham_Mau;
    private Sprite[] boom;
    private Sprite[] fire_small;
    private Sprite[] fire_big;
    private int TongSoBom;
    private int TongSoBomDangNo;
    private int Loaibom;

    public MH_Play(Game app) {
        super(true);
        this.app = app;
        setFullScreenMode(true);
        GameDesign game = new GameDesign();
        iX = 90;
        iY = 90;
        DoLeft = 0;
        DoRight = 0;
        DoUp = 0;
        DoDown = 0;
        isDatBom = 1;
        try {
            BoomMan = game.getBombMan();
            Base = game.getBase();
            ChuongNgai = game.getVatCan();
            Ground = game.getGround();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void Init() {
        Loaibom = 1;
        TongSoBom = 1;
        TongSoBomDangNo = 0;
        this.delay = 20;
        this.design = new GameDesign();
        this.design1 = new GameDesign_1();
        this.timer = new Timer();
        this.fire_small = new Sprite[2];
        this.fire_big = new Sprite[2];
        this.boom = new Sprite[2];
        try {
            this.Boss = this.design1.getTrum();
            this.VatPham_BanhXe = this.design1.getVatpham_banhxe();
            this.VatPham_Lua = this.design1.getVatpham_lua();
            this.VatPham_Mau = this.design1.getVatpham_mau();

            this.fire_small[0] = this.design.getBomNo();
            this.fire_small[0].setVisible(false);
            this.fire_small[1] = this.design.getBomNo();
            this.fire_small[1].setVisible(false);
            this.fire_big[0] = this.design1.getFire_big();
            this.fire_big[0].setVisible(false);
            this.fire_big[1] = this.design1.getFire_big();
            this.fire_big[1].setVisible(false);
            this.boom[0] = this.design.getBom();
            this.boom[0].setVisible(false);
            this.boom[1] = this.design.getBom();
            this.boom[1].setVisible(false);

        } catch (IOException ex) {
            ex.printStackTrace();
        }
        this.layerManager = new LayerManager();
        layerManager.append(this.Boss);
        layerManager.append(ChuongNgai);
        KhoiTaoMonster();
        KhoiTaoGach();
        layerManager.append(this.VatPham_BanhXe);
        layerManager.append(this.VatPham_Lua);
        layerManager.append(this.VatPham_Mau);
        layerManager.append(BoomMan);
        layerManager.append(this.fire_small[0]);
        layerManager.append(this.fire_small[1]);
        layerManager.append(this.fire_big[0]);
        layerManager.append(this.fire_big[1]);
        layerManager.append(this.boom[0]);
        layerManager.append(this.boom[1]);

        BoomMan.setPosition(iX, iY);
        BoomMan.defineCollisionRectangle(2, 2, 26, 26);
        try {
            this.design.updateLayerManagerForScene01(layerManager);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        for (int i = 0; i < nMonster; i++) {
            Monster_Animated[i].ThemVatCanTinh(this.ChuongNgai);
            for (int j = 0; j < nGach; j++) {
                this.Monster_Animated[i].ThemVatCanDong(Gach[j]);
            }
            for (int k = 0; k < nMonster; k++) {
                if (k != i) {
                    this.Monster_Animated[i].ThemVatCanDong(Monster[k]);
                }
            }

            Monster_Animated[i].HoatDong();
        }
        Boss_Animated = new Boss(Boss, 0, 0);
        Boss_Animated.NamNghi();
        Boss_Animated.ThemVatCanTinh(this.ChuongNgai);
        this.Boss.setPosition(450, 90);
        Boss_Animated.HoatDong();
        this.VatPham_BanhXe.setPosition(300, 390);
        this.VatPham_Lua.setPosition(90, 210);
        this.VatPham_Mau.setPosition(360, 90);
    }

    public void KhoiTaoGach() {
        Gach = new Sprite[nGach];
        for (int i = 0; i < nGach; i++) {
            try {
                Gach[i] = design.getBrick();
                Gach[i].defineCollisionRectangle(2, 2, 26, 26);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        Gach[0].setPosition(30 * 6, 30 * 3);
        Gach[1].setPosition(30 * 8, 30 * 3);
        Gach[2].setPosition(30 * 12, 30 * 3);
        Gach[3].setPosition(30 * 14, 30 * 3);
        Gach[4].setPosition(30 * 4, 30 * 5);
        Gach[5].setPosition(30 * 5, 30 * 5);
        Gach[6].setPosition(30 * 8, 30 * 5);
        Gach[7].setPosition(30 * 10, 30 * 5);
        Gach[8].setPosition(30 * 12, 30 * 5);
        Gach[9].setPosition(30 * 14, 30 * 5);
        Gach[10].setPosition(30 * 4, 30 * 7);
        Gach[11].setPosition(30 * 6, 30 * 7);
        Gach[12].setPosition(30 * 9, 30 * 7);
        Gach[13].setPosition(30 * 6, 30 * 9);
        Gach[14].setPosition(30 * 8, 30 * 9);
        Gach[15].setPosition(30 * 10, 30 * 9);
        Gach[16].setPosition(30 * 11, 30 * 11);
        Gach[17].setPosition(30 * 12, 30 * 11);
        Gach[18].setPosition(30 * 14, 30 * 11);
        Gach[19].setPosition(30 * 12, 30 * 13);
        Gach[20].setPosition(30 * 13, 30 * 13);
        Gach[21].setPosition(30 * 4, 30 * 13);
        Gach[22].setPosition(30 * 3, 30 * 8);
        for (int i = 0; i < nGach; i++) {
            this.layerManager.append(Gach[i]);
        }
    }

    public void KhoiTaoMonster() {
        Monster = new Sprite[nMonster];
        Monster_Animated = new NamDoc[nMonster];
        for (int i = 0; i < nMonster; i++) {
            try {
                Monster[i] = design.getMonster01();
                layerManager.append(Monster[i]);
                Monster_Animated[i] = new NamDoc(Monster[i], 0, 0);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        Monster[0].setPosition(30 * 7, 30 * 3);
        Monster[1].setPosition(30 * 15, 30 * 3);
        Monster[2].setPosition(30 * 11, 30 * 4);
        Monster[3].setPosition(30 * 5, 30 * 6);
        Monster[4].setPosition(30 * 13, 30 * 7);
        Monster[5].setPosition(30 * 12, 30 * 9);
        Monster[6].setPosition(30 * 16, 30 * 9);
        Monster[7].setPosition(30 * 11, 30 * 9);
        Monster[8].setPosition(30 * 3, 30 * 13);
        Monster[9].setPosition(30 * 15, 30 * 13);
    }

    private void processKeys(int KeyStates) {

        switch (KeyStates) {
            case LEFT_PRESSED:
                if (DoLeft == 0) {
                    BoomMan.setFrameSequence(this.design.BombMan_left);
                    DoLeft = 1;
                    DoRight = 0;
                    DoUp = 0;
                    DoDown = 0;
                }
                calculateCharMovement(LEFT_PRESSED);
                status = 1;
                break;
            case RIGHT_PRESSED:
                if (DoRight == 0) {
                    BoomMan.setFrameSequence(this.design.BombMan_right);
                    DoLeft = 0;
                    DoRight = 1;
                    DoUp = 0;
                    DoDown = 0;
                }
                calculateCharMovement(RIGHT_PRESSED);
                status = 2;
                break;
            case UP_PRESSED:
                if (DoUp == 0) {
                    BoomMan.setFrameSequence(this.design.BombMan_up);
                    DoLeft = 0;
                    DoRight = 0;
                    DoUp = 1;
                    DoDown = 0;
                }
                calculateCharMovement(UP_PRESSED);
                status = 3;
                break;
            case DOWN_PRESSED:
                if (DoDown == 0) {
                    BoomMan.setFrameSequence(this.design.BombMan_down);
                    DoLeft = 0;
                    DoRight = 0;
                    DoUp = 0;
                    DoDown = 1;
                }
                calculateCharMovement(DOWN_PRESSED);
                status = 4;
                break;
            case FIRE_PRESSED: {
                DatBomb();
                break;
            }
        }
    }

    private void calculateCharMovement(int keyState) {
        /*check which way to move and change direction*/
        if ((keyState & LEFT_PRESSED) != 0) {
            iX = Math.max(0, iX - speed);
            KidDirection = keyState;
            KidState = charWalk;
        } else if ((keyState & RIGHT_PRESSED) != 0) {
            iX = Math.min(Ground.getWidth() - BoomMan.getWidth(), iX + speed);
            KidDirection = keyState;
            KidState = charWalk;
        } else if ((keyState & UP_PRESSED) != 0) {
            iY = Math.max(iY - speed, 0);
            KidDirection = keyState;
            KidState = charWalk;
        } else if ((keyState & DOWN_PRESSED) != 0) {
            iY = Math.min(iY + speed, Ground.getHeight() - BoomMan.getHeight());
            KidDirection = keyState;
            KidState = charWalk;
        }
        if (KidState == charWalk) {
            if (KidDirection == RIGHT_PRESSED) {
                BoomMan.nextFrame();
            } else if (KidDirection == LEFT_PRESSED) {
                BoomMan.nextFrame();
            } else if (KidDirection == UP_PRESSED) {
                BoomMan.nextFrame();
            } else if (KidDirection == DOWN_PRESSED) {
                BoomMan.nextFrame();
            }
            if (!BoomMan.collidesWith(ChuongNgai, true)) {
                BoomMan.setPosition(iX, iY);
                KidState = charWalk;
                switch (status) {
                    case 1: {
                        DieuChinhKhungNhin(this.scnX - speed, this.scnY);
                        break;
                    }
                    case 2: {
                        DieuChinhKhungNhin(this.scnX + speed, this.scnY);
                        break;
                    }
                    case 3: {
                        DieuChinhKhungNhin(this.scnX, this.scnY - speed);
                        break;
                    }
                    case 4: {
                        DieuChinhKhungNhin(this.scnX, this.scnY + speed);
                        break;
                    }
                }
            }
            if (BoomMan.collidesWith(ChuongNgai, false) || VaChamGach()) {
                KidState = charStop;
                if (status == 1) {
                    BoomMan.setPosition(iX += speed, iY);
                } else if (status == 2) {
                    BoomMan.setPosition(iX -= speed, iY);
                } else if (status == 3) {
                    BoomMan.setPosition(iX, iY += speed);
                } else if (status == 4) {
                    BoomMan.setPosition(iX, iY -= speed);
                }
            }
        }
        flushGraphics();
    }

    public void Start() {
        Thread t = new Thread(this);
        t.start();
    }

    public void run() {
        Graphics g = getGraphics();
        while (true) {
            this.DrawScreen(g);
            this.processKeys(getKeyStates());
            this.UpdateGame();
            try {
                Thread.sleep(40);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    public void UpdateGame() {
        if (CollideWithFire(this.BoomMan)) {
            Die();
        }
        for (int i = 0; i < nMonster; i++) {
            if (CollideWithFire(this.Monster[i])) {
                this.Monster_Animated[i].Chet();
                int x = Monster[i].getX();
                int y = Monster[i].getY();
                Monster[i].setFrameSequence(design.Monster01_died);
                Animation animation = new Animation(Monster[i], design.Monster01_died.length);
                timer.scheduleAtFixedRate(animation, 0, 200);
            }
        }
        for (int i = 0; i < nGach; i++) {
            if (CollideWithFire(Gach[i])) {
                int x = Gach[i].getX();
                int y = Gach[i].getY();
                Gach[i].setFrameSequence(design.fired);
                Gach[i].setFrame(0);
                Animation animation = new Animation(Gach[i], design.fired.length);
                timer.scheduleAtFixedRate(animation, 0, 200);
            }
        }

        if (BoomMan.collidesWith(this.VatPham_BanhXe, true)) {
            this.VatPham_BanhXe.setVisible(false);
            this.speed += 4;
        }
        if (BoomMan.collidesWith(this.VatPham_Lua, true)) {
            Loaibom = 2;
            TongSoBom = 2;
            this.VatPham_Lua.setVisible(false);
        }
        if (BoomMan.collidesWith(this.VatPham_Mau, true)) {
            this.VatPham_Mau.setVisible(false);
        }

    }

    public boolean CollideWithFire(Sprite s) {
        if (s.collidesWith(this.fire_big[0], true) || s.collidesWith(this.fire_big[1], true) || s.collidesWith(this.fire_small[0], true) || s.collidesWith(this.fire_small[1], true)) {
            return true;
        }
        return false;
    }

    private void DrawScreen(Graphics g) {
        g.setColor(0xffffff);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(0x0000ff);
        layerManager.paint(g, 0, 0);
        flushGraphics();
    }

    public void DieuChinhKhungNhin(int x, int y) {
        int sx = this.BoomMan.getX();
        int sy = this.BoomMan.getY();
        int xmin = this.scnX + MIN_BUFFER;
        int xmax = this.scnX + this.getWidth() - this.BoomMan.getWidth() - MIN_BUFFER;
        int ymin = this.scnY + MIN_BUFFER;
        int ymax = this.scnY + this.getHeight() - this.BoomMan.getHeight() - MIN_BUFFER;
        if (sx >= xmin && sx <= xmax && sy >= ymin && sy <= ymax) {
            return;
        }
        if (this.KidDirection == LEFT_PRESSED && sx >= xmin) {
            return;
        }
        if (this.KidDirection == RIGHT_PRESSED && sx <= xmax) {
            return;
        }
        if (this.KidDirection == UP_PRESSED && sy >= ymin) {
            return;
        }
        if (this.KidDirection == DOWN_PRESSED && sy <= ymax) {
            return;
        }
        if (x < this.Base.getX()) {
            this.scnX = this.Base.getX();
        } else if (x > this.Base.getX() + this.Base.getWidth() - this.getWidth()) {
            this.scnX = this.Base.getX() + this.Base.getWidth() - this.getWidth();
        } else {
            this.scnX = x;
        }
        if (y < this.Base.getY()) {
            this.scnY = this.Base.getY();
        } else if (y > this.Base.getY() + this.Base.getHeight() - this.getHeight()) {
            this.scnY = this.Base.getY() + this.Base.getHeight() - this.getHeight();
        } else {
            this.scnY = y;
        }
        this.layerManager.setViewWindow(this.scnX, this.scnY, this.getWidth(), this.getHeight());
    }

    public synchronized void DatBomb() {
        System.out.println(TongSoBomDangNo);
        if (TongSoBomDangNo < TongSoBom) {
            int x = this.BoomMan.getX();
            int y = this.BoomMan.getY();
            x = (int) (x / 30) * 30;
            y = (int) (y / 30) * 30;
            if (Loaibom == 1) {
                if (this.fire_small[0].isVisible() == false && this.boom[0].isVisible() == false) {
                    this.boom[0].setPosition(x, y);
                    this.boom[0].setVisible(true);
                    main.MH_Play.BombAnimation bomb_animation = new BombAnimation(this.boom[0], this.fire_small[0], x, y);
                    this.timer.scheduleAtFixedRate(bomb_animation, 0, 500);
                    TongSoBomDangNo++;
                } else if (this.fire_small[1].isVisible() == false && this.boom[1].isVisible() == false) {
                    this.boom[1].setPosition(x, y);
                    this.boom[1].setVisible(true);
                    main.MH_Play.BombAnimation bomb_animation = new BombAnimation(this.boom[1], this.fire_small[1], x, y);
                    this.timer.scheduleAtFixedRate(bomb_animation, 0, 500);
                    TongSoBomDangNo++;
                }
            } else if (Loaibom == 2) {
                if (this.fire_big[0].isVisible() == false && this.boom[0].isVisible() == false) {
                    this.boom[0].setPosition(x, y);
                    this.boom[0].setVisible(true);
                    main.MH_Play.BombAnimation bomb_animation = new BombAnimation(this.boom[0], this.fire_big[0], x, y);
                    this.timer.scheduleAtFixedRate(bomb_animation, 0, 1000);
                    TongSoBomDangNo++;
                } else if (this.fire_big[1].isVisible() == false && this.boom[1].isVisible() == false) {
                    this.boom[1].setPosition(x, y);
                    this.boom[1].setVisible(true);
                    main.MH_Play.BombAnimation bomb_animation = new BombAnimation(this.boom[1], this.fire_big[1], x, y);
                    this.timer.scheduleAtFixedRate(bomb_animation, 0, 1000);
                    TongSoBomDangNo++;
                }
            }
        }


    }

    public void Die() {
        this.dieAnimation = new DieAnimation(BoomMan);
        this.timer.scheduleAtFixedRate(dieAnimation, 0, 200);
    }

    public boolean VaChamGach() {
        for (int i = 0; i < nGach; i++) {
            if (this.BoomMan.collidesWith(Gach[i], false)) {
                return true;
            }
        }
        return false;
    }

    private class FireAnimation extends TimerTask {

        private Sprite Fire;

        public FireAnimation(Sprite fire) {
            this.Fire = fire;
        }

        public void run() {
            if (this.Fire.getFrame() != 3) {
                this.Fire.nextFrame();
            } else {
                this.Fire.setFrame(0);
                this.Fire.setVisible(false);
                this.cancel();
                MH_Play.this.TongSoBomDangNo--;
            }
        }
    }

    public class BombAnimation extends TimerTask {

        private Sprite Bomb = null;
        private Sprite Fire = null;
        private int x;
        private int y;

        public BombAnimation(Sprite b, Sprite fire, int x, int y) {
            this.Bomb = b;
            this.Fire = fire;
            this.x = x;
            this.y = y;
            this.Bomb.setFrame(0);
        }

        public void run() {
            if (this.Bomb.getFrame() != 5) {
                this.Bomb.nextFrame();
            } else {
                this.Bomb.setVisible(false);
                if (Fire.getWidth() == 90) {
                    Fire.setPosition(this.x - 30, this.y - 30);
                } else {
                    Fire.setPosition(this.x - 60, this.y - 60);
                }

                main.MH_Play.FireAnimation fire = new FireAnimation(Fire);
                Fire.setVisible(true);
                MH_Play.this.timer.scheduleAtFixedRate(fire, 0, 200);
                this.cancel();
            }
        }
    }

    public class DieAnimation extends TimerTask {

        private Sprite BoomMan = MH_Play.this.BoomMan;

        public DieAnimation(Sprite b) {
            this.BoomMan = b;
            this.BoomMan.setFrameSequence(MH_Play.this.design.BombMan_died);
        }

        public void run() {
            if (this.BoomMan.getFrame() != 5) {
                this.BoomMan.nextFrame();
            } else {
                this.BoomMan.setVisible(false);
                MH_Play.this.timer.scheduleAtFixedRate(MH_Play.this.dieAnimation, 0, 100);
                this.cancel();
            }
        }
    }
}
